<template>
  <div v-loading="step2Data.loading" class="my-container">
    <!-- 步骤条 -->
    <div class="my-card">
      <el-steps :active="stepsActive" finish-status="success">
        <el-step v-for="item in mySteps" :key="item.title" :title="item.title" :description="item.description" />
      </el-steps>
      <el-button style="margin-top: 12px" @click="stepsPrevious">上一步</el-button>
      <el-button style="margin-top: 12px" @click="stepsNext">下一步</el-button>
    </div>
    <!-- 第一步： 上传 -->
    <div v-show="stepsActive === 0" class="my-card">
      <upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
      <el-table :data="step0Data.tableData" border highlight-current-row style="width: 100%; margin-top: 20px">
        <el-table-column v-for="item of step0Data.tableHeader" :key="item" :prop="item" :label="item" />
      </el-table>
    </div>
    <!-- 第二步： 修改 -->
    <div v-show="stepsActive === 1" class="my-card">
      <div class="flex-row">
        <el-select v-model="step1Data.selectValue" style="width: 180px; margin-right: 10px" placeholder="搜索条件">
          <el-option v-for="(item, index) in step1Data.tableHeader" :key="item" :label="item" :value="index" />
        </el-select>
        <el-input
          v-model="step1Data.searchText"
          maxlength="255"
          style="width: 180px; margin-right: 10px"
          :placeholder="'按“' + step1Data.tableHeader[step1Data.selectValue] + '”搜索'"
          @input="handleInput"
        />
        <el-button v-waves type="primary" icon="el-icon-plus" @click="showDialog.addRowsDialog = true">
          添加
        </el-button>
        <el-button v-waves type="primary" icon="el-icon-download" @click="showDialog.downloadTableDialog = true">
          导出
        </el-button>
        <el-button v-waves type="primary" plain @click="resetIndexOfTable"> 重整序号 </el-button>
        <div style="flex: 1" />
        <el-button v-waves style="margin-left: 60px" type="warning" icon="el-icon-edit-outline" @click="onAlterRowsUpdata">
          编辑
        </el-button>
        <el-button v-waves type="danger" icon="el-icon-close" @click="showDialog.deleteRowsDialog=true"> 删除 </el-button>
      </div>
      <!-- step1的主表格 -->
      <el-table
        v-show="step1Data.searchText === ''"
        :row-class-name="tableRowClassName"
        :data="step1Data.tableData"
        max-height="780"
        border
        highlight-current-row
        style="width: 100%; margin-top: 20px"
        @row-click="onRowClick"
      >
        <el-table-column type="index" />
        <el-table-column v-for="item of step1Data.tableHeader" :key="item" :prop="item" :label="item" />
      </el-table>
      <!-- step1的临时表格 -->
      <el-table v-show="!(step1Data.searchText === '')" :data="step1Data.filterTableData" max-height="780" border style="width: 100%; margin-top: 20px">
        <el-table-column type="index" />
        <el-table-column v-for="item of step1Data.tableHeader" :key="item" :prop="item" :label="item" />
      </el-table>
    </div>
    <!-- 第三步： 保存 -->
    <div v-show="stepsActive === 2" class="my-card">
      <div class="flex-row">
        <div v-for="(item, index) in step2Data.data" :key="index" style="height: 48px">
          <label class="radio-label" style="padding-left: 16px">{{ item.title }}：</label>
          <el-input v-model="item.value" maxlength="255" style="width: 200px" placeholder="" />
        </div>
      </div>
      <el-button style="margin: 12px 0 0 0" type="primary" icon="el-icon-upload" @click="onUploadMyPaper">
        上传服务器
      </el-button>
    </div>

    <!-- 导出文件对话框 -->
    <el-dialog title="导出到本地" :visible.sync="showDialog.downloadTableDialog">
      <div class="dialogForm">
        <FilenameOption v-model="downloadTable.filename" />
        <AutoWidthOption v-model="downloadTable.autoWidth" />
        <BookTypeOption v-model="downloadTable.bookType" />
        <div>
          <el-button :loading="downloadTable.downloadLoading" style="margin: 12px 0 0 0" type="primary" icon="el-icon-document" @click="handleDownload">
            导出表格
          </el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 添加新行对话框 -->
    <el-dialog v-el-drag-dialog title="添加新行" :visible.sync="showDialog.addRowsDialog">
      <div class="dialogForm">
        <div class="flex-row">
          <div v-for="(item, index) in addRows.rowArr " :key="item.title" style="height: 48px">
            <label class="radio-label" style="padding-left: 16px">{{ item.title }}：</label>
            <el-input v-model="addRows.rowArr[index].value" maxlength="255" style="width: 200px" placeholder="" />
          </div>
        </div>
        <div>
          <el-select v-model="addRows.selectValue" placeholder="请选择">
            <el-option v-for="(item, index) in addRows.selectOptions" :key="index" :label="item.label" :value="index" />
          </el-select>
          <el-input-number v-if="addRows.selectValue == 2" v-model="addRows.addWhere" :min="1" :max="step1Data.tableData.length" />
          <el-button style="margin: 12px 20px 0 20px" type="primary" @click="addNewTableRows">
            添加新行
          </el-button>
          <el-button style="margin: 12px 20px 0 20px" type="warning" @click="cleanAddTableRowsForm">
            清空输入框
          </el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 修改某一行对话框 -->
    <el-dialog :title="'正在修改：第'+(alterRows.selectRow+1)+'行'" :visible.sync="showDialog.alterRowsDialog">
      <div class="dialogForm">
        <div class="flex-row">
          <div v-for="(item, index) in alterRows.rowArr " :key="item.title" style="height: 48px">
            <label class="radio-label" style="padding-left: 16px">{{ item.title }}：</label>
            <el-input v-model="alterRows.rowArr[index].value" maxlength="255" style="width: 200px" placeholder="" />
          </div>
        </div>
        <div>
          <el-button style="margin: 12px 20px 0 20px" type="primary" @click="alterTableRows">
            更新此行
          </el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 删除某一行 -->
    <el-dialog :title="'正在删除：第'+(alterRows.selectRow+1)+'行'" :visible.sync="showDialog.deleteRowsDialog">
      <div class="dialogForm">
        <div>请仔细核对原始数据，删除后无法恢复。</div>
        <div>{{ step1Data.tableData[alterRows.selectRow] }}</div>
        <el-button style="margin: 12px 20px 0 20px" type="danger" @click="deleteTableRows">
          删除此行
        </el-button>
      </div>
    </el-dialog>
    <!-- ———————————— -->
  </div>
</template>

<script>
import UploadExcelComponent from '@/components/UploadExcel/index.vue' // 上传excel
import waves from '@/directive/waves/index.js' // 水波纹指令
import elDragDialog from '@/directive/el-drag-dialog' // 可拖拽dialog
import { mapGetters } from 'vuex'

// options components
import FilenameOption from './components/FilenameOption'
import AutoWidthOption from './components/AutoWidthOption'
import BookTypeOption from './components/BookTypeOption'

// 引用API
import { uploadPaper } from '@/api/paper'

export default {
  name: 'UploadExcel',
  components: {
    UploadExcelComponent,
    FilenameOption,
    AutoWidthOption,
    BookTypeOption
  },
  directives: {
    waves,
    elDragDialog
  },
  data() {
    return {
      stepsActive: 0,
      mySteps: [
        {
          title: '步骤 1',
          description: '上传Excel文件（文件格式请查看帮助页面）'
        },
        { title: '步骤 2', description: '查看和修改试卷表格' },
        { title: '步骤 3', description: '录入该试卷的相关信息，生成试卷' }
      ], // 步骤条描述文本
      step0Data: {
        tableHeader: [],
        tableData: []
      }, // 步骤0数据
      step1Data: {
        tableHeader: [],
        tableData: [],
        filterTableData: [], // 搜索框使用的临时表格，只用来展示
        searchText: '', // 搜索词
        selectValue: 0 // 搜索框搜索条件
      }, // 步骤1数据
      step2Data: {
        data: [
          { title: '考卷名称', value: '' }
          // { title: "分数", value: "" },
          // { title: "配图", value: "" },
          // { title: "题目类型", value: "" },
          // { title: "正确选项", value: "" },
          // { title: "选项A", value: "" },
          // { title: "选项B", value: "" },
          // { title: "选项C", value: "" },
          // { title: "选项D", value: "" },
          // { title: "选项E", value: "" },
          // { title: "选项F", value: "" },
        ],
        loading: false
      },
      showDialog: {
        downloadTableDialog: false,
        addRowsDialog: false,
        alterRowsDialog: false,
        deleteRowsDialog: false
      }, // 是否显示对话框
      alterRows: {
        rowJSON: {},
        rowArr: [],
        selectRow: undefined
      }, // 修改行
      addRows: {
        rowJSON: {},
        rowArr: [],
        selectOptions: [
          { label: '在开头' },
          { label: '在结尾' },
          { label: '指定行' }
        ], // 选择器选项
        selectValue: 0, // 选择器选择的插入位置 0:在开头，1：在结尾..。设置见selectOptions
        addWhere: 1 // 当选择器选择自定义插入位置时候，判定在哪里插入。注意，从1开始计数
      }, // 新增行
      downloadTable: {
        downloadLoading: false, // 正在下载
        filename: '', // 下载文件的文件名
        autoWidth: false, // 是否自动列宽
        bookType: 'xlsx' // 生成的格式
      } // 下载文件
    }
  },
  computed: {
    ...mapGetters(['name', 'avatar', 'roles'])
  },
  methods: {
    /**
     * 步骤条点击上一步
     */
    stepsPrevious() {
      this.stepsPreviousRestData()
      if (this.stepsActive-- <= 0) this.stepsActive++
    },
    /**
     * 步骤条点击下一步
     */
    stepsNext() {
      // if (!this.stepsCheck()) return
      this.stepsCheck()
      this.stepNextUpData()
      if (this.stepsActive++ >= this.mySteps.length - 1) this.stepsActive--
    },
    /**
     * 条件检测与数据校验，阻止步骤跳转
     */
    stepsCheck() {
      if (this.stepsActive === 0 && this.step0Data.tableHeader.length === 0) {
        this.$message({
          message: '由于您未上传任何文件，系统为您自动补全了模板',
          type: 'warning'
        })
        this.step0Data.tableHeader = ['序号', '分数', '题干', '配图', '题目类型', '正确选项', '选项A', '选项B', '选项C', '选项D', '选项E', '选项F']
        this.step0Data.tableData.push({ '序号': 1, '分数': 10, '题干': '（自动生成的题目）请问一加一等于几？', '配图': '', '题目类型': '单选', '正确选项': 'A', '选项A': '等于3', '选项B': '等于2', 'row_index': 0 })
        this.updataStep1InSomeTime()
        return false
      }
      return true
    },
    /**
     * 点击上一步时，清除某些不安全数据
     */
    stepsPreviousRestData() {
      if (this.stepsActive === 1) {
        this.step1Data.filterTableData = []
        this.step1Data.searchText = ''
        this.step0Data.tableHeader = []
        this.step0Data.tableData = []
      }
    },
    /**
     * 点击下一步时，更新必要的数据
     */
    stepNextUpData() {
      if (this.stepsActive === 0) {
        this.step1Data.tableHeader = this.step0Data.tableHeader.slice()
        this.step1Data.tableData = this.step0Data.tableData.slice()
      }
      if (this.stepsActive === 1) {
        this.resetIndexOfTable()
      }
    },
    /**
     * 步骤0：上传Excel前验证，文件大小验证
     */
    beforeUpload(file) {
      const isLt1M = file.size / 1024 / 1024 < 1
      if (isLt1M) {
        return true
      }
      this.$message({
        message: '请不要上传大于1mb的文件',
        type: 'warning'
      })
      return false
    },
    /**
     * 步骤0：上传Excel成功，将数据写入数组
     */
    handleSuccess({ results, header }) {
      this.step0Data.tableData = results
      this.step0Data.tableHeader = header
      this.addRows.rowArr = []
      this.addRows.rowJSON = {}
      this.alterRows.rowJSON = []
      this.alterRows.rowArr = {}
      header.map((e) => {
        this.addRows.rowJSON[e] = e
      })
      for (const i in this.addRows.rowJSON) {
        this.addRows.rowArr.push({
          title: this.addRows.rowJSON[i],
          value: ''
        })
      }
      this.alterRows.rowJSON = JSON.parse(JSON.stringify(this.addRows.rowJSON))
      this.alterRows.rowArr = JSON.parse(JSON.stringify(this.addRows.rowArr))
      // console.log('————上传成功————')
      // console.log(this.addRows.rowJSON, "***", this.addRows.rowArr);
    },

    /**
     * 补丁：让不上传文件时也能正确的显示step1
     */
    updataStep1InSomeTime() {
      this.addRows.rowArr = []
      this.addRows.rowJSON = {}
      this.alterRows.rowJSON = []
      this.alterRows.rowArr = {}
      this.step0Data.tableHeader.map((e) => {
        this.addRows.rowJSON[e] = e
      })
      for (const i in this.addRows.rowJSON) {
        this.addRows.rowArr.push({
          title: this.addRows.rowJSON[i],
          value: ''
        })
      }
      this.alterRows.rowJSON = JSON.parse(JSON.stringify(this.addRows.rowJSON))
      this.alterRows.rowArr = JSON.parse(JSON.stringify(this.addRows.rowArr))
      // console.log('————(伪)上传成功————')
      // console.log(this.addRows.rowJSON, "***", this.addRows.rowArr);
    },

    /**
     * 动态搜索框：
     * 用户输入任何字符时，即隐藏table，显示filterTable。通过for循环提取要搜索的字符串
     * 使用indexof进行对比，如果用户输入的字符包括，则将该列push进filterTable。
     * tempArry数组仅用来调试，可删除
     * cvpv 2021年5月10日 13:34:38
     */
    handleInput(value) {
      this.step1Data.filterTableData = []
      for (let i = 0; i < this.step1Data.tableData.length; i++) {
        if (
          JSON.stringify(
            this.step1Data.tableData[i][
              this.step1Data.tableHeader[this.step1Data.selectValue]
            ]
          ).indexOf(value) !== -1
        ) {
          this.step1Data.filterTableData.push(this.step1Data.tableData[i])
        }
      }
    },
    /**
     * 开始下载文件，导出表格
     */
    handleDownload() {
      this.downloadTable.downloadLoading = true
      import('@/vendor/Export2Excel').then((excel) => {
        const filterVal = this.step1Data.tableHeader
        const list = this.step1Data.tableData
        const data = this.formatJson(filterVal, list)
        console.log(data)
        excel.export_json_to_excel({
          header: this.step1Data.tableHeader, // 表头 必填
          data,
          filename: this.downloadTable.filename,
          autoWidth: this.downloadTable.autoWidth,
          bookType: this.downloadTable.bookType
        })
        this.downloadTable.downloadLoading = false
      })
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map((v) =>
        filterVal.map((j) => {
          // console.log("测试",j,"/",v[j]);
          return v[j]
        })
      )
    },
    /**
     * 添加新行
     */
    addNewTableRows() {
      let j = 0
      for (const i in this.addRows.rowJSON) {
        this.addRows.rowJSON[i] = this.addRows.rowArr[j].value
        j++
      }
      if (this.addRows.selectValue === 0) {
        this.step1Data.tableData.unshift(
          JSON.parse(JSON.stringify(this.addRows.rowJSON))
        )
        this.$message({
          message:
            '添加成功！插入位置：' +
            (this.addRows.selectValue === 0
              ? '开头'
              : '哇哦，意料之外的情况出现了！'),
          type: 'success'
        })
      }
      if (this.addRows.selectValue === 1) {
        this.step1Data.tableData.push(
          JSON.parse(JSON.stringify(this.addRows.rowJSON))
        )
        this.$message({
          message:
            '添加成功！插入位置：' +
            (this.addRows.selectValue === 1
              ? '结尾'
              : '哇哦，意料之外的情况出现了！'),
          type: 'success'
        })
      }
      if (this.addRows.selectValue === 2) {
        this.step1Data.tableData.splice(
          this.addRows.addWhere - 1,
          0,
          JSON.parse(JSON.stringify(this.addRows.rowJSON))
        )
        this.$message({
          message:
            '添加成功！插入位置：第 ' +
            (this.addRows.selectValue === 2
              ? this.addRows.addWhere
              : '哇哦，意料之外的情况出现了！') +
            ' 行',
          type: 'success'
        })
      }
    },
    /**
     * 添加行时，清除输入框
     */
    cleanAddTableRowsForm() {
      let j = 0
      for (const i in this.addRows.rowJSON) {
        this.addRows.rowArr[j].value = ''
        this.addRows.rowJSON[i] = ''
        j++
      }
    },
    /**
     * 给table每格rows加上属性
     */
    tableRowClassName({ row, rowIndex }) {
      row.row_index = rowIndex
    },
    /**
     * 点击了某一行
     */
    onRowClick(row, event, column) {
      this.alterRows.selectRow = row.row_index
      // console.log(row.row_index)
    },
    /**
     * 修改某一行前，对 alterRows 进行初始化
     */
    onAlterRowsUpdata() {
      if (this.alterRows.selectRow === undefined) {
        this.$message({
          message: '你未选择任何行！',
          type: 'warning'
        })
        return false
      }
      if (this.step1Data.searchText !== '') {
        this.$message({
          message:
            '您正在使用搜索功能，不允许选择某行进行更改（因为搜索时，当前显示是搜索结果临时表）',
          type: 'error'
        })
        return false
      }
      for (const i in this.alterRows.rowJSON) {
        this.alterRows.rowJSON[i] = ''
      }
      const selectRow = this.alterRows.selectRow
      for (const i in this.step1Data.tableData[selectRow]) {
        this.alterRows.rowJSON[i] = this.step1Data.tableData[selectRow][i]
      }

      for (let i = 0; i < this.alterRows.rowArr.length; i++) {
        this.alterRows.rowArr[i].value = this.alterRows.rowJSON[
          this.alterRows.rowArr[i].title
        ]
      }
      // console.log('after：', this.alterRows.rowArr)
      this.showDialog.alterRowsDialog = true
    },
    /**
     * 更新此行
     */
    alterTableRows() {
      for (let i = 0; i < this.alterRows.rowArr.length; i++) {
        this.alterRows.rowJSON[
          this.alterRows.rowArr[i].title
        ] = this.alterRows.rowArr[i].value
      }
      this.step1Data.tableData.splice(
        this.alterRows.selectRow,
        1,
        JSON.parse(JSON.stringify(this.alterRows.rowJSON))
      )
      this.$message({
        message:
          '更新成功！更新位置：第 ' + (this.alterRows.selectRow + 1) + ' 行',
        type: 'success'
      })
    },
    /**
     * 删除某行
     */
    deleteTableRows() {
      if (this.alterRows.selectRow === undefined) {
        this.$message({
          message: '你未选择任何行！',
          type: 'warning'
        })
        return
      }
      if (this.step1Data.tableData.length === 1) {
        this.$message({
          message:
            '哇哦！无法删除，因为表格不能为空',
          type: 'error'
        })
        return
      }
      this.step1Data.tableData.splice(this.alterRows.selectRow, 1)
      this.$message({
        message:
          '删除成功！删除位置：第 ' + (this.alterRows.selectRow + 1) + ' 行',
        type: 'success'
      })
    },
    /**
     * 重整序号
     */
    resetIndexOfTable() {
      if (!this.step1Data.tableData[0]['序号']) {
        this.$message({
          message:
            '您导入的表格有误，找不到序号',
          type: 'error'
        })
        return false
      }
      for (let i = 0; i < this.step1Data.tableData.length; i++) {
        this.step1Data.tableData[i]['序号'] = i + 1
      }
      this.$message({
        message:
          '重整序号成功',
        type: 'success'
      })
      return true
    },
    /**
     * 上传数据库
     */
    async onUploadMyPaper() {
      // uploadPaper(this.step1Data.tableHeader, this.step1Data.tableData, this.step2Data.filename)
      // console.log('来自vuex:',this.name)
      if (this.step2Data.data[0].value === '') {
        this.$message({
          message:
            '必须输入试卷标题！',
          type: 'error'
        })
        return
      }
      const data = {
        tableHeader: this.step1Data.tableHeader,
        tableData: this.step1Data.tableData,
        paperTitle: this.step2Data.data[0].value,
        paperAuthor: this.name
      }
      this.step2Data.loading = true
      try {
        await uploadPaper(data)
      } catch {
        this.step2Data.loading = false
        return
      }
      this.step2Data.loading = false
      this.$message({
        message:
          '上传成功',
        type: 'success'
      })
    }
  }
}
</script>

<style scoped>
.my-container {
  padding: 32px;
  background-color: #e6e6e6;
  min-height: calc(100vh - 84px);
}
.my-card {
  padding: 16px;
  margin-bottom: 32px;
  background-color: #fff;
}
.flex-row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
</style>
